package com.dgut.utils;

import com.dgut.pojo.JwtProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 */
@Component
public class JwtTokenUtil {
    //自定义jwt配置类
    @Autowired
    JwtProperties jwtProperties ;

    static final String CLAIM_KEY_USERNAME = "sub";
    static final String CLAIM_KEY_AUDIENCE = "audience";
    static final String CLAIM_KEY_CREATED = "created";

    public Claims getClaimsFromToken(String token){
        Claims claims;
        try {

            claims = Jwts.parser()
                    .setSigningKey(jwtProperties.getSalt())
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
    //获取用户名
    public String getUsernameFromToken(String token){
        String username;
        try {
            username = this.getClaimsFromToken(token).getSubject();
        } catch (Exception e) {
            username=null;
        }
        return username;
    }
    public Date getCreatedDateFromToken(String token){
        Date createdDate;
        try {
            Claims claims = getClaimsFromToken(token);
            createdDate = new Date((long)claims.get(CLAIM_KEY_CREATED));
        } catch (Exception e) {
           createdDate = null;
        }
        return createdDate;
    }

    public Date getExpirationDateFromToken(String token){
        Date expiration;
        try {
            expiration = this.getClaimsFromToken(token).getExpiration();
        } catch (Exception e) {
            expiration = null;
        }
        return expiration;
    }

    public String getAudienceFromToken(String token){
        String audience;
        try {
            audience = (String) this.getClaimsFromToken(token).get(CLAIM_KEY_AUDIENCE);
        } catch (Exception e) {
            audience = null;
        }
        return audience;
    }

    //设置过期时间
    private Date generateExpirationDate(){
        return new Date(System.currentTimeMillis()+jwtProperties.getExpirationMillisecond());
    }
  
    private Boolean isTokenExpired(String token){
        Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    public String generateToken(String username){
        Map<String,Object> claims = new HashMap<>();
        claims.put(CLAIM_KEY_USERNAME,username);
        claims.put(CLAIM_KEY_CREATED,new Date());
        return generateToken(claims);
    }

    String generateToken(Map<String,Object> claims){
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512,jwtProperties.getSalt())
                .compact();
    }

    //验证token是否有效
    public Boolean validateToken(String token, UserDetails userDetails){
        User user = (User) userDetails;
        final String username = getUsernameFromToken(token);
        final  Date created = getCreatedDateFromToken(token);
        if(username!=null && created!=null){
            return (username.equals(user.getUsername()) && !isTokenExpired(token));
        }
        return false;
    }

}
